
#include "container/ind_queue.h"
#include <stdio.h>

#include "unity.h"


void test_IndQueueInit(void)
{
    uint8_t buf[10];
    cotIndQueue_t queue;

    cotIndQueue_Init(&queue, buf, sizeof(buf));

    TEST_ASSERT_EQUAL_PTR(buf, queue.pBuf);
    TEST_ASSERT_EQUAL_UINT(sizeof(buf), queue.limit);
    TEST_ASSERT_EQUAL_UINT(sizeof(buf), queue.waterLevel);
    TEST_ASSERT_EQUAL_UINT(0, queue.wIdx);
    TEST_ASSERT_EQUAL_UINT(0, queue.rIdx);
    TEST_ASSERT_EQUAL_UINT(0, queue.count);
    TEST_ASSERT_TRUE(queue.isEmpty);
}

void test_IndQueueEmpty(void)
{
    uint8_t buf[10];
    cotIndQueue_t queue;

    cotIndQueue_Init(&queue, buf, sizeof(buf));

    TEST_ASSERT_TRUE(cotIndQueue_Empty(&queue));

    int data = 42;
    cotIndQueue_Push(&queue, &data, sizeof(data));
    TEST_ASSERT_FALSE(cotIndQueue_Empty(&queue));
}

void test_IndQueueFull(void)
{
    uint8_t buf[10];
    cotIndQueue_t queue;

    cotIndQueue_Init(&queue, buf, sizeof(buf));
    TEST_ASSERT_FALSE(cotIndQueue_Full(&queue, sizeof(int)));

    int data = 42;

    for (int i = 0; i < sizeof(buf) / sizeof(int); i++)
    {
        cotIndQueue_Push(&queue, &data, sizeof(data));
    }

    TEST_ASSERT_TRUE(cotIndQueue_Full(&queue, sizeof(int)));
}

void test_IndQueueSize(void)
{
    uint8_t buf[10];
    cotIndQueue_t queue;

    cotIndQueue_Init(&queue, buf, sizeof(buf));
    TEST_ASSERT_EQUAL_UINT(0, cotIndQueue_Size(&queue));

    int data = 42;
    cotIndQueue_Push(&queue, &data, sizeof(data));
    TEST_ASSERT_EQUAL_UINT(1, cotIndQueue_Size(&queue));
}

void test_IndQueueFront(void)
{
    uint8_t buf[10];
    cotIndQueue_t queue;

    cotIndQueue_Init(&queue, buf, sizeof(buf));

    int data = 42;
    cotIndQueue_Push(&queue, &data, sizeof(data));

    int data1 = 80;
    cotIndQueue_Push(&queue, &data, sizeof(data));

    int data2 = -400;
    cotIndQueue_Push(&queue, &data, sizeof(data));

    size_t length;
    int *pData = (int *)cotIndQueue_Front(&queue, &length);
    TEST_ASSERT_EQUAL_INT(data, *pData);
    TEST_ASSERT_EQUAL_INT(sizeof(data), length);
}


void test_IndQueuePush(void)
{
    uint8_t buf[10];
    cotIndQueue_t queue;

    cotIndQueue_Init(&queue, buf, sizeof(buf));

    int data = 42;
    int ret = cotIndQueue_Push(&queue, &data, sizeof(data));
    TEST_ASSERT_EQUAL_INT(0, ret);
    TEST_ASSERT_EQUAL_UINT(1, cotIndQueue_Size(&queue));
}

void test_IndQueuePop(void)
{
    uint8_t buf[10];
    cotIndQueue_t queue;

    cotIndQueue_Init(&queue, buf, sizeof(buf));
    int data = 42;
    cotIndQueue_Push(&queue, &data, sizeof(data));

    cotIndQueue_Pop(&queue);
    TEST_ASSERT_TRUE(cotIndQueue_Empty(&queue));
}

void test_IndQueueSwap(void)
{
    uint8_t buf1[20];
    uint8_t buf2[20];
    cotIndQueue_t queue1, queue2;

    cotIndQueue_Init(&queue1, buf1, sizeof(buf1));
    cotIndQueue_Init(&queue2, buf2, sizeof(buf2));

    int data1 = 1, data2 = 2, data3 = 3;

    cotIndQueue_Push(&queue1, &data1, sizeof(data1));
    cotIndQueue_Push(&queue1, &data2, sizeof(data2));

    TEST_ASSERT_EQUAL_UINT(2, cotIndQueue_Size(&queue1));

    cotIndQueue_Push(&queue2, &data3, sizeof(data3));

    TEST_ASSERT_EQUAL_UINT(1, cotIndQueue_Size(&queue2));

    cotIndQueue_Swap(&queue1, &queue2);

    size_t length;
    int *pData = (int *)cotIndQueue_Front(&queue2, &length);
    TEST_ASSERT_EQUAL_INT(data1, *pData);
    TEST_ASSERT_EQUAL_INT(sizeof(data1), length);
    cotIndQueue_Pop(&queue2);

    pData = (int *)cotIndQueue_Front(&queue2, &length);
    TEST_ASSERT_EQUAL_INT(data2, *pData);
    TEST_ASSERT_EQUAL_INT(sizeof(data2), length);
    cotIndQueue_Pop(&queue2);

    TEST_ASSERT_TRUE(cotIndQueue_Empty(&queue2));

    pData = (int *)cotIndQueue_Front(&queue1, &length);
    TEST_ASSERT_EQUAL_INT(data3, *pData);
    TEST_ASSERT_EQUAL_INT(sizeof(data3), length);
    cotIndQueue_Pop(&queue1);

    TEST_ASSERT_TRUE(cotIndQueue_Empty(&queue1));
}

void test_IndQueueSwapEmpty(void)
{
    uint8_t buf1[10];
    uint8_t buf2[10];
    cotIndQueue_t queue1, queue2;

    cotIndQueue_Init(&queue1, buf1, sizeof(buf1));
    cotIndQueue_Init(&queue2, buf2, sizeof(buf2));

    cotIndQueue_Swap(&queue1, &queue2);

    TEST_ASSERT_TRUE(cotIndQueue_Empty(&queue1));
    TEST_ASSERT_TRUE(cotIndQueue_Empty(&queue2));
}

void test_IndQueueSwapNonEmptyAndEmpty(void)
{
    uint8_t buf1[20];
    uint8_t buf2[20];
    cotIndQueue_t queue1, queue2;

    cotIndQueue_Init(&queue1, buf1, sizeof(buf1));
    cotIndQueue_Init(&queue2, buf2, sizeof(buf2));

    int data1 = 1, data2 = 2;

    cotIndQueue_Push(&queue1, &data1, sizeof(data1));
    cotIndQueue_Push(&queue1, &data2, sizeof(data2));

    cotIndQueue_Swap(&queue1, &queue2);

    TEST_ASSERT_TRUE(cotIndQueue_Empty(&queue1));
    TEST_ASSERT_FALSE(cotIndQueue_Empty(&queue2));

    TEST_ASSERT_EQUAL_UINT(0, cotIndQueue_Size(&queue1));
    TEST_ASSERT_EQUAL_UINT(2, cotIndQueue_Size(&queue2));
}

int test_IndQueue(void) 
{
    UNITY_BEGIN();  // 启动测试

    RUN_TEST(test_IndQueueInit);
    RUN_TEST(test_IndQueueEmpty);
    RUN_TEST(test_IndQueueFull);
    RUN_TEST(test_IndQueueSize);
    RUN_TEST(test_IndQueueFront);
    RUN_TEST(test_IndQueuePush);
    RUN_TEST(test_IndQueuePop);
    RUN_TEST(test_IndQueueSwap);

    RUN_TEST(test_IndQueueSwapEmpty);
    RUN_TEST(test_IndQueueSwapNonEmptyAndEmpty);

    UNITY_END();  // 结束测试

    return 0;
}  